

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% INIT

% parameters
NCOMP = 2; % number of mixture components
USE_WEEKEND = 0; % including weekend tag in models

% path
oldPath = path;
addpath(genpath('../../data/ours/'));

% meta-feature labels
fid = fopen('mflabels.txt');
C = textscan(fid, '%d %s');
fclose(fid);
metafeatureIDs = C{1};
metafeatureLABELs = C{2};
clear C;
numMetafeatures = length(metafeatureIDs);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  TRAIN  %
%                                                                         %
%  A meta-feature classifier is built by computing a MoG for each sensor  %
%  and grouping these models by meta-feature. These clusters represent    %
%  our model for each meta-feature.                                       %
%                                                                         %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

load firings_B_sec.txt;
if ~USE_WEEKEND,
  firings_B_sec = firings_B_sec(:,1:3);
end
load mfmap_B.txt;
sensorIDs_B = mfmap_B(:,1);
numSensors_B = length(sensorIDs_B);

allmog_B = cell(numSensors_B,1);
mf_clusters_B = cell(numMetafeatures,1);

fprintf('Computing mixture models for sensors of house B.\n');

for idx=1:numSensors_B,
  X = firings_B_sec(firings_B_sec(:,1)==sensorIDs_B(idx),2:end);
  allmog_B{idx} = gm_process_sensor(X, 'Blue', 0, NCOMP);
end

fprintf('Computing meta-feature clusters for house B.\n');

for idx=1:numMetafeatures,
  mog_ids = mfmap_B(:,2)==metafeatureIDs(idx);
  fprintf('Meta-feature %2d (%s): %d sensors.\n', ...
      metafeatureIDs(idx),metafeatureLABELs{idx},sum(mog_ids));
  if sum(mog_ids) == 0,
    % no sensors corresponding to this meta-feature
    mf_clusters_B{idx} = cell(0);
  else
    mf_clusters_B{idx} = allmog_B(mog_ids);
  end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  TEST  %
%                                                                         %
%  Find for each 'anonymous' cluster (meta-feature of house C) the        %
%  best 'candidate' match (meta-feature of house B).                      %
%                                                                         %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

load firings_C_sec.txt;
if ~USE_WEEKEND,
  firings_C_sec = firings_C_sec(:,1:3);
end
load mfmap_C.txt;
sensorIDs_C = mfmap_C(:,1);
numSensors_C = length(sensorIDs_C);

fprintf('\nComputing mixture models for sensors of house C.\n');

allmog_C = cell(numSensors_C,1);
for idx=1:numSensors_C,
  X = firings_C_sec(firings_C_sec(:,1)==sensorIDs_C(idx),2:end);
  allmog_C{idx} = gm_process_sensor(X, 'Blue', 0, NCOMP);
end

fprintf('Computing meta-feature clusters for house C.\n');

mf_clusters_C = cell(numMetafeatures,1);
for idx=1:numMetafeatures,
  mog_ids = mfmap_C(:,2)==metafeatureIDs(idx);
  fprintf('Meta-feature %2d (%s): %d sensors.\n', ...
      metafeatureIDs(idx),metafeatureLABELs{idx},sum(mog_ids));
  if sum(mog_ids) == 0,
    % no sensors corresponding to this meta-feature
    mf_clusters_C{idx} = cell(0);
  else
    mf_clusters_C{idx} = allmog_C(mog_ids);
  end
end

fprintf('\nFinding best matches for houseC->houseB (heuristic).\n');

anonymousClusters = mf_clusters_C;
candidateClusters = mf_clusters_B;

availableAnonymous = ones(length(anonymousClusters),1);
availableCandidates = ones(length(candidateClusters),1);

for idx=1:length(anonymousClusters),
  if isempty(anonymousClusters{idx}),
    availableAnonymous(idx) = 0;
  end
end

for idx=1:length(candidateClusters),
  if isempty(candidateClusters{idx}),
    availableCandidates(idx) = 0;
  end
end

while sum(availableAnonymous) > 0,
  
  if sum(availableCandidates) == 0,
    availableCandidates = ones(length(candidateClusters),1);
    for idx=1:length(candidateClusters),
      if isempty(candidateClusters{idx}),
        availableCandidates(idx) = 0;
      end
    end
  end
  
  matchingScores = inf(length(anonymousClusters),1);
  
  minDiv = inf;
  ordAnonymous = inf;
  ordCandidate = inf;
  
  % for each anonymous cluster still to be processed
  for idxAnonymous=1:length(anonymousClusters),
    if ~availableAnonymous(idxAnonymous),
      continue;
    end

    anonymous = anonymousClusters{idxAnonymous};    
    curOrdCandidate = inf;
    curMinDiv = inf;

    % compute divergence to all available candidates
    for idxCandidate=1:length(candidateClusters),
      if ~availableCandidates(idxCandidate),
        continue;
      end
      
      candidate = candidateClusters{idxCandidate};
      curDiv = compute_cluster_divergence(anonymous, candidate);
      
      if curDiv < curMinDiv,
        curMinDiv = curDiv;
        curOrdCandidate = idxCandidate;
      end      
    end
    
    if curMinDiv < minDiv,
      minDiv = curMinDiv;
      ordAnonymous = idxAnonymous;
      ordCandidate = curOrdCandidate;
    end
  end
  
  % print match with lowest score
  fprintf('%s/C -> %s/B (%f)\n', ...
    metafeatureLABELs{ordAnonymous}, ...
    metafeatureLABELs{ordCandidate}, ...
    minDiv);
  
  % remove matched clusters from anonymous and candidate list
  availableAnonymous(ordAnonymous) = 0;
  availableCandidates(ordCandidate) = 0;
  
end

% restore old MATLAB path
path(oldPath);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  RESULTS  %
%                                                                         %
%   Computing mixture models for sensors of house B.
%   Computing meta-feature clusters for house B.
%   Meta-feature  1 (KitchHeat): 3 sensors.
%   Meta-feature  2 (Toilet): 1 sensors.
%   Meta-feature  3 (BathroomDoor): 1 sensors.
%   Meta-feature  4 (Kitchen): 3 sensors.
%   Meta-feature  5 (KitchStor): 2 sensors.
%   Meta-feature  6 (Outside): 1 sensors.
%   Meta-feature  7 (SleepDoor): 1 sensors.
%   Meta-feature  8 (Sleep): 4 sensors.
%   Meta-feature  9 (Bathroom): 2 sensors.
%   Meta-feature 10 (Other): 0 sensors.
% 
%   Computing mixture models for sensors of house C.
%   Computing meta-feature clusters for house C.
%   Meta-feature  1 (KitchHeat): 1 sensors.
%   Meta-feature  2 (Toilet): 3 sensors.
%   Meta-feature  3 (BathroomDoor): 1 sensors.
%   Meta-feature  4 (Kitchen): 6 sensors.
%   Meta-feature  5 (KitchStor): 2 sensors.
%   Meta-feature  6 (Outside): 1 sensors.
%   Meta-feature  7 (SleepDoor): 1 sensors.
%   Meta-feature  8 (Sleep): 3 sensors.
%   Meta-feature  9 (Bathroom): 2 sensors.
%   Meta-feature 10 (Other): 1 sensors.
%
%   NCOMP = 2
%
%   Finding best matches for houseC->houseB (heuristic).
%   Bathroom/C -> BathroomDoor/B (0.367435)
%   Kitchen/C -> Toilet/B (1.000786)
%   Sleep/C -> Bathroom/B (1.895027)
%   BathroomDoor/C -> KitchHeat/B (2.453446)
%   Toilet/C -> SleepDoor/B (2.836980)
%   KitchStor/C -> Outside/B (2.961161)
%   Outside/C -> KitchStor/B (4.396576)
%   Other/C -> Kitchen/B (4.485329)
%   SleepDoor/C -> Sleep/B (5.375277)
%   KitchHeat/C -> Outside/B (4.912894)
%
%   NCOMP = 1
% 
%   Finding best matches for houseC->houseB (heuristic).
%   Bathroom/C -> Toilet/B (0.074946)
%   Other/C -> Kitchen/B (0.136360)
%   KitchStor/C -> BathroomDoor/B (0.238807)
%   Kitchen/C -> Bathroom/B (0.682579)
%   SleepDoor/C -> Sleep/B (0.868090)
%   KitchHeat/C -> KitchHeat/B (0.885880)
%   Outside/C -> KitchStor/B (1.344011)
%   Toilet/C -> SleepDoor/B (2.797162)
%   Sleep/C -> Outside/B (7.601405)
%   BathroomDoor/C -> KitchHeat/B (1.477482)
%                                                                         %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
